﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Configuration;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Data;
using System.IO;
using System.Xml.Linq;
using LibTracker;

namespace posttracker.Classes
{
    public class Country
    {
        public string Name { get; set; }
        public int CountryID { get; set; }
    }


    public class Loader
    {
        private const int GuestId = 4;

        private static XDocument _xDoc =
            new XDocument(
                new XElement("TrackNumbers",
                    new XElement("TrackNumber",
                        new XElement("Number", "rf094887335sg"),
                        new XElement("aUserId", "1"),
                        new XElement("Records",
                            new XElement("Record",
                                new XAttribute("Data", "2012-07-13"),
                                new XAttribute("Event", "Получение отправления в учреждение обмена, исход"),
                                new XAttribute("PostService", "SINGAPORE S05")),
                            new XElement("Record",
                                new XAttribute("Data", "2012-07-13"),
                                new XAttribute("Event", "Отправка отправления из учреждения обмена"),
                                new XAttribute("PostService", "SINGAPORE S05")),
                            new XElement("Record",
                                new XAttribute("Data", "2012-08-01"),
                                new XAttribute("Event", "Получение отправления в учреждение обмена, вход"),
                                new XAttribute("PostService", "MINSK PI 2")),
                            new XElement("Record",
                                new XAttribute("Data", "2012-08-02"),
                                new XAttribute("Event", "Передача отправления таможне, вход"),
                                new XAttribute("PostService", "MINSK PI 2")),
                            new XElement("Record",
                                new XAttribute("Data", "2012-08-06"),
                                new XAttribute("Event", "Запись информации таможни об отправлении, вход"),
                                new XAttribute("PostService", "MINSK PI 2"))))));

        /*
         *for async request e.g. mobile phone
         */
        //const string ApiUrl = "http://posttracker.azurewebsites.net/";
        public async void getDataAsync()
        {
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri(WebConfigurationManager.AppSettings["apiUrl"]);

            HttpResponseMessage response = await client.GetAsync("api/track/2");
            Product[] contacts = await response.Content.ReadAsAsync<Product[]>();
        }

        public Product getData(int id)
        {
            try
            {
                HttpClient client = new HttpClient();
                client.BaseAddress = new Uri(WebConfigurationManager.AppSettings["apiUrl"]);

                // Add an Accept header for JSON format.
                client.DefaultRequestHeaders.Accept.Add(
                    new MediaTypeWithQualityHeaderValue("application/json"));

                // List all products.
                HttpResponseMessage response = client.GetAsync("api/track/" + id).Result;  // Blocking call!

                if (response.IsSuccessStatusCode)
                {
                    // Parse the response body. Blocking!
                    var product = response.Content.ReadAsAsync<Product>().Result;

                    return product;


                }
                else
                {
                    throw new HttpRequestException(HttpStatusCode.NotFound.ToString());

                }
            }
            catch (HttpRequestException er)
            {
                return null;
            }
            catch (AggregateException ex)
            {
                return null;
            }

            return null;

        }

        public static IList<TrackNumbers> GetTrackNumbersInfo(int aUserId)
        {

            using (var client = new WebClient())
            {
                client.Headers[HttpRequestHeader.ContentType] = "application/json;charset=utf-8";
                try
                {
                    client.BaseAddress = WebConfigurationManager.AppSettings["apiUrl"];
                    var json = Newtonsoft.Json.JsonConvert.SerializeObject(new { user = new User() { Id = aUserId, Email = "fshadow77@gmail.com" }, id = 0 });
                    string resultJson = client.UploadString("api/track/gettrackdatabyuserid/", json);

                    IList<TrackDataInfo> lstResponse = (IList<TrackDataInfo>)Newtonsoft.Json.JsonConvert.DeserializeObject(resultJson, typeof(IList<TrackDataInfo>));


                    if (lstResponse != null)
                    {

                        IList<TrackNumbers> lst = new List<TrackNumbers>();

                        foreach (TrackDataInfo elem in lstResponse)
                        {
                            TrackNumbers tn = new TrackNumbers();
                            tn.TrackNumber = elem.TrackNumber;
                            tn.UserId = elem.UserId;

                            XDocument xDoc = XDocument.Parse(elem.Records);
                            IEnumerable<XElement> xRecords = xDoc.Element("Records").Elements();

                            tn.ListRecords = new List<Record>();

                            foreach (XElement rec in xRecords)
                            {
                                Record tmp = new Record();
                                tmp.DateTime = DateTime.Parse(rec.Attribute("date").Value);
                                tmp.Event = rec.Attribute("event").Value;
                                tmp.PostService = rec.Attribute("postservice").Value;
                                tn.ListRecords.Add(tmp);
                            }

                            lst.Add(tn);
                        }

                        return lst;

                    }
                    else
                    {
                        return null;
                    }
                }
                catch (WebException)
                {
                    throw new WebException("Error on user request.");
                }
            }

        }

        public static IList<TrackNumbers> GetTrackNumbersInfo(string aTrackNumber)
        {

            using (var client = new WebClient())
            {
                client.Headers[HttpRequestHeader.ContentType] = "application/json;charset=utf-8";
                try
                {
                    client.BaseAddress = WebConfigurationManager.AppSettings["apiUrl"];
                    var json = Newtonsoft.Json.JsonConvert.SerializeObject(new TrackDataInfo() { TrackNumber = aTrackNumber, UserId = GetUserID() });
                    string resultJson = client.UploadString("api/track/GetTrackDataByTrackNum/", json);

                    IList<TrackDataInfo> lstResponse = (IList<TrackDataInfo>)Newtonsoft.Json.JsonConvert.DeserializeObject(resultJson, typeof(IList<TrackDataInfo>));


                    if (lstResponse != null)
                    {

                        IList<TrackNumbers> lst = new List<TrackNumbers>();

                        foreach (TrackDataInfo elem in lstResponse)
                        {
                            TrackNumbers tn = new TrackNumbers();
                            tn.TrackNumber = elem.TrackNumber;
                            tn.UserId = elem.UserId;

                            XDocument xDoc = XDocument.Parse(elem.Records);
                            IEnumerable<XElement> xRecords = xDoc.Element("Records").Elements();

                            tn.ListRecords = new List<Record>();

                            foreach (XElement rec in xRecords)
                            {
                                Record tmp = new Record();
                                tmp.DateTime = DateTime.Parse(rec.Attribute("date").Value);
                                tmp.Event = rec.Attribute("event").Value;
                                tmp.PostService = rec.Attribute("postservice").Value;
                                tn.ListRecords.Add(tmp);
                            }

                            lst.Add(tn);
                        }

                        return lst;

                    }
                    else
                    {
                        return null;
                    }
                }
                catch (WebException ex)
                {
                    throw new WebException(ex.Message);
                }
            }

        }

        /////////////////////////////////////////////////////////////////////////////////////////////
        #region Заглушки


        public static IList<Country> GetCountry()
        {
            return new List<Country> { new Country { CountryID = 0, Name = "Беларусь" }, new Country { CountryID = 1, Name = "Сингапур" }, new Country { CountryID = 2, Name = "Китай" } };
        }

        public static bool isLogged()
        {
            //return true;
            return false;
        }

        public static int GetUserID()
        {
            return GuestId; // 4;
        }

        public static IList<TrackNumbers> GetGuestTrackNumbersInfo(string aTrackNumber, int aCountryDestanationId)
        {
            // здесь получить данные из бд и проверить кому принадлежит трек
            IList<TrackNumbers> tmpDB = null;
            try
            {
                tmpDB = GetTrackNumbersInfo(aTrackNumber);
            }
            catch (WebException ex)
            {
                if (ex.Message.IndexOf("(406)") > 0)
                {
                    throw new WebException(ex.Message);
                }
            }

            if (isLogged() && tmpDB != null)
            {
                throw new NumberIsExistsException();
            }


            // Получение данний инфы происходит через использование моей библиотеки
            TrakNumbers trakNumbers = new TrakNumbers();
            var input = new List<DataInput>
                            {
                                new DataInput
                                    {
                                        TrackNumber = aTrackNumber,
                                        CountryDestanationID = aCountryDestanationId
                                    }
                            };

            var tmp = trakNumbers.CheckTrackNumbers(input);

            IList<TrackNumbers> tmpWeb = new List<TrackNumbers>();

            foreach (ResultRequestFromPostService info in tmp)
            {
                TrackNumbers trackNumbers = new TrackNumbers();
                trackNumbers.TrackNumber = info.TrackNumber;
                trackNumbers.ListRecords = new List<Record>();

                foreach (PostRecord rec in info.Records)
                {
                    Record record = new Record();
                    record.DateTime = rec.Date;
                    record.Event = rec.Record;
                    record.PostService = rec.PostServiceName;

                    trackNumbers.ListRecords.Add(record);
                }

                tmpWeb.Add(trackNumbers);
            }


            // Далее убираем дубликаты событий и обновляем инфу в БД
            var first = tmpDB.FirstOrDefault();
            var second = tmpWeb.FirstOrDefault();

            List<TrackNumbers> result = new List<TrackNumbers>();

            if (second != null)
            {
                IList<Record> resultRecords = null;
                if (first != null)
                {
                    if (first.ListRecords.Count < second.ListRecords.Count)
                    {

                        IEnumerable<Record> r = second.ListRecords;

                        foreach (Record record in first.ListRecords)
                        {
                            r = r
                                .Where(
                                    s =>
                                    !(s.DateTime == record.DateTime && s.Event == record.Event &&
                                    s.PostService == record.PostService));
                        }

                        if (r != null)
                            foreach (Record record in r)
                            {
                                first.ListRecords.Add(record);
                            }


                    }



                    //var rrr = first.ListRecords.Union(second.ListRecords);
                    resultRecords = first.ListRecords;
                    result.Add(first);
                }
                else
                {
                    resultRecords = second.ListRecords;
                    result.Add(second);
                }

                //second.ListRecords = resultRecords;

                XElement xRecords;
                XDocument xml = new XDocument();
                xml.Add(xRecords = new XElement("Records"));
                foreach (Record record in resultRecords)
                {
                    xRecords.Add(new XElement("Record",
                                              new XAttribute("date", record.DateTime.ToShortDateString()),
                                              new XAttribute("event", record.Event),
                                              new XAttribute("postservice", record.PostService)));
                }



                string queryStr = WebConfigurationManager.AppSettings["apiUrl"] + "api/track/InsertTrackData/";
                var httpWebRequest = (HttpWebRequest)WebRequest.Create(queryStr);
                httpWebRequest.ContentType = "text/json;charset=utf-8";

                httpWebRequest.Method = "POST";

                try
                {
                    using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
                    {
                        TrackDataInfo obj = new TrackDataInfo()
                                                {
                                                    TrackNumber = aTrackNumber,
                                                    UserId = GetUserID(),
                                                    Records = xml.ToString(SaveOptions.DisableFormatting)
                                                };

                        var json =
                            Newtonsoft.Json.JsonConvert.SerializeObject(obj);

                        streamWriter.Write(json);
                        streamWriter.Flush();
                        streamWriter.Close();

                        var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                    }
                }
                catch (WebException ex)
                {
                    throw new WebException(ex.Message);
                }

            }

            return result;
        }



        public static void AddNewDataInDB(IList<TrackNumbers> lst)
        {




            //using (var client = new WebClient())
            //{
            //    client.Headers[HttpRequestHeader.ContentType] = "application/json;charset=utf-8";
            //    try
            //    {
            //        client.BaseAddress = WebConfigurationManager.AppSettings["apiUrl"];
            //        var json =
            //            Newtonsoft.Json.JsonConvert.SerializeObject(new TrackDataInfo()
            //                                                            {
            //                                                                TrackNumber = aTrackNumber,
            //                                                                UserId = GetUserID()
            //                                                            });
            //        string resultJson = client.UploadString("api/track/GetTrackDataByTrackNum/", json);

            //        IList<TrackDataInfo> lstResponse =
            //            (IList<TrackDataInfo>)
            //            Newtonsoft.Json.JsonConvert.DeserializeObject(resultJson, typeof(IList<TrackDataInfo>));

            //    }
            //}














            XElement trackNumbers = _xDoc.Element("TrackNumbers");

            foreach (TrackNumbers trackNumber in lst)
            {

                XElement records;

                trackNumbers.Add(
                new XElement("TrackNumber",
                        new XElement("Number", trackNumber.TrackNumber),
                        new XElement("aUserId", GetUserID()),
                        records = new XElement("Records")));

                foreach (Record rec in trackNumber.ListRecords)
                {
                    string data = rec.DateTime.ToShortDateString();
                    records.Add(new XElement("Record",
                               new XAttribute("Data", data),
                               new XAttribute("Event", rec.Event),
                               new XAttribute("PostService", rec.PostService)));

                }

            }

        }

        #endregion


    }
}